package com.sihan.framework.etm.service.business.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.framework.model.ApiResult;
import com.sihan.framework.etm.common.PageRequest;
import com.sihan.framework.etm.common.util.DateUtils;
import com.sihan.framework.etm.common.util.EtmWebUtil;
import com.sihan.framework.etm.common.util.ImgUtils;
import com.framework.model.PageResult;
import com.framework.mybatis.Condition;
import com.framework.mybatis.service.impl.BaseServiceImpl;
import com.framework.util.PageUtils;
import com.framework.util.WebUtils;
import com.github.pagehelper.PageHelper;
import com.sihan.framework.etm.common.CacheOperatorInfo;
import com.sihan.framework.etm.common.CommonBiz;
import com.sihan.framework.etm.dto.business.BorrowToolTaskDTO;
import com.sihan.framework.etm.dto.business.DeviceLastWarehouseParamDTO;
import com.sihan.framework.etm.dto.business.DeviceWarehouseDTO;
import com.sihan.framework.etm.dto.business.ToolBorrowReturnRecordDTO;
import com.sihan.framework.etm.entity.DeviceSurplusTool;
import com.sihan.framework.etm.entity.baseData.DeviceModel;
import com.sihan.framework.etm.entity.baseData.ToolModel;
import com.sihan.framework.etm.entity.business.ToolBorrowDetail;
import com.sihan.framework.etm.entity.business.ToolBorrowMaster;
import com.sihan.framework.etm.entity.business.ToolBorrowPlanDetail;
import com.sihan.framework.etm.entity.business.ToolBorrowReturnRecord;
import com.sihan.framework.etm.entity.business.ToolException;
import com.sihan.framework.etm.entity.business.ToolInspectDetail;
import com.sihan.framework.etm.entity.business.ToolReturnDetail;
import com.sihan.framework.etm.entity.business.ToolReturnMaster;
import com.sihan.framework.etm.entity.business.ToolUseTask;
import com.sihan.framework.etm.entity.business.ToolWarehouseDetail;
import com.sihan.framework.etm.enums.CacheKeyName;
import com.sihan.framework.etm.enums.FormatImgPre;
import com.sihan.framework.etm.enums.OperateType;
import com.sihan.framework.etm.mapper.CommonMapper;
import com.sihan.framework.etm.mapper.baseData.DeviceMapper;
import com.sihan.framework.etm.mapper.baseData.ToolMapper;
import com.sihan.framework.etm.mapper.business.InspectDetailMapper;
import com.sihan.framework.etm.mapper.business.ToolBorrowDetailMapper;
import com.sihan.framework.etm.mapper.business.ToolBorrowMapper;
import com.sihan.framework.etm.mapper.business.ToolBorrowMasterMapper;
import com.sihan.framework.etm.mapper.business.ToolBorrowReturnRecordMapper;
import com.sihan.framework.etm.mapper.business.ToolExceptionMapper;
import com.sihan.framework.etm.mapper.business.ToolReturnDetailMapper;
import com.sihan.framework.etm.mapper.business.ToolReturnMasterMapper;
import com.sihan.framework.etm.mapper.business.ToolUseTaskMapper;
import com.sihan.framework.etm.schema.master.BorrowReturnRecordSchema;
import com.sihan.framework.etm.service.baseData.DeviceService;
import com.sihan.framework.etm.service.business.BorrowService;
import com.sihan.framework.etm.vo.business.BorrowDetailVO;
import com.sihan.framework.etm.vo.business.BorrowPlanVO;
import com.sihan.framework.etm.vo.business.CacheOcrModel;
import com.sihan.framework.etm.vo.business.DevicePdVO;
import com.sihan.framework.etm.vo.business.ReturnDetailVO;
import com.sihan.framework.etm.vo.business.ToolBorrowReturnRecordVO;
import com.sihan.framework.etm.vo.business.ToolQueryVO;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class BorrowServiceImpl extends BaseServiceImpl<ToolModel, String> implements BorrowService{

	@Autowired
	private ToolBorrowMapper toolBorrowMapper;
	@Autowired
	private ToolBorrowMasterMapper toolBorrowMasterMapper;
	@Autowired
	private ToolBorrowDetailMapper toolBorrowDetailMapper;
	@Autowired
	private ToolReturnMasterMapper toolReturnMasterMapper;
	@Autowired
	private ToolReturnDetailMapper toolReturnDetailMapper;
	@Autowired
	private ToolBorrowReturnRecordMapper toolBorrowReturnRecordMapper;
	@Autowired
	private ToolMapper toolMapper;
	@Autowired
	private DeviceMapper deviceMapper;
	@Autowired
	private CommonBiz commonBiz;
	@Autowired
	private ImgUtils imgUtil;
	@Autowired
	private ToolExceptionMapper toolExceptionMapper;
	@Autowired
	private InspectDetailMapper inspectDetailMapper;
	@Autowired
	private DeviceService deviceService;
	@Autowired
	private CommonMapper commonMapper;
	@Autowired
	private ToolUseTaskMapper toolUseTaskMapper;
	
	public static final Object lock = new Object();
	
	@Override
	public List<BorrowPlanVO> selectLastNoDoneBorrowPlan() {
		//获取ocr结果
		CacheOcrModel cache = (CacheOcrModel)CacheOperatorInfo.getMapValue(
				CacheKeyName.CACHE_BORROW_OCR_SCAN.getValue(), null);
		//选择的任务
		String taskId = (String)CacheOperatorInfo.getMapValue(
				CacheKeyName.CACHE_BORROW_TASK_ID.getValue(), null);
		//手写任务
		BorrowToolTaskDTO toolTask = (BorrowToolTaskDTO)CacheOperatorInfo.getMapValue(
				CacheKeyName.CACHE_BORROW_REASON.getValue(), null);
		List<BorrowPlanVO> result = null;
		
		String borrowMasterId = (String)CacheOperatorInfo.getMapValue(CacheKeyName.BUSINESS_MASTER_ID.getValue(), null);
		String userId = commonBiz.checkValidatedUserId();
		if(StringUtils.isBlank(borrowMasterId)) {
			borrowMasterId = checkBorrowMasterId(userId,borrowMasterId);
		}
		
		if(null != cache) {
			result = toolBorrowMapper.selectBorrowPlanByMasterId(cache.getBorrowPlanMasterId(),borrowMasterId);
		}
		
		if(!StringUtils.isBlank(taskId)) {
			result = toolBorrowMapper.selectBorrowStatisticsByMasterId(taskId, borrowMasterId);
		}
		
		if(null != toolTask) {
			result = toolBorrowMapper.selectBorrowStatisticsByMasterId("0", borrowMasterId);
		}

		if(null != result && !result.isEmpty()) {
			this.calToolBorrow(result,borrowMasterId);
		}
		return result;
	}

	@Override
	public PageResult<BorrowDetailVO> selectBorrowDetailByMasterId(PageRequest dto) {
		String userId = commonBiz.checkValidatedUserId();
		String  masterId = (String)CacheOperatorInfo.getMapValue(CacheKeyName.BUSINESS_MASTER_ID.getValue(), null);
		if(StringUtils.isBlank(userId)) {
			masterId = this.checkBorrowMasterId(userId, masterId);
		}
		PageHelper.startPage(dto);
	    List<BorrowDetailVO> result = toolBorrowMapper.selectBorrowDetailByPlanId(masterId);
	    if(null != result && !result.isEmpty()) {
	    	result.stream().forEach(vo->{
	    		vo.setHasExpired(commonBiz.checkToolHasExpired(
	    				StringUtils.isBlank(vo.getExpiredTime())?null:DateUtils.getInstance().getDateByStr(vo.getExpiredTime(), DateUtils.getInstance().SDF_HH)));
	    	});
	    }
	    return PageUtils.toPageResult(result);
	}
	
	/**
	 * 
	 * @description 计算实际领用的数量
	 * @param result
	 * @auther 韩兵
	 * @Date 2020年7月7日
	 * @return void
	 */
	private void calToolBorrow(List<BorrowPlanVO> result,String masterId) {
		List<BorrowPlanVO> noPlan = new ArrayList<BorrowPlanVO>();
		List<BorrowDetailVO> details = toolBorrowMapper.selectBorrowDetailByPlanId(masterId);
		if(null != details && !details.isEmpty()) {
			if(null != result && !result.isEmpty()) {
				Map<String,List<BorrowDetailVO>> mapDetails = details.stream().
						collect(Collectors.groupingBy(BorrowDetailVO::getModelId));
				final Iterator<Entry<String, List<BorrowDetailVO>>> entries = mapDetails.entrySet().iterator();
				//设置已在计划中的数量
				result.stream().forEach(vo->{
					while(entries.hasNext()) {
						Entry<String, List<BorrowDetailVO>> detail = entries.next();
						String[] standardIds = vo.getModelId().split(",");
						if(ArrayUtils.contains(standardIds, detail.getKey())) {
							vo.setActualQuatity(new BigDecimal(detail.getValue().size()));
						}
					}
				});
				//设置未在计划中的数量
				Iterator<Entry<String, List<BorrowDetailVO>>> entriesentries = mapDetails.entrySet().iterator();
				while(entriesentries.hasNext()) {
					Boolean find = false;
					Entry<String, List<BorrowDetailVO>> detail = entriesentries.next();
					for(BorrowPlanVO plan : result) {
						if (plan.getModelId().equals(detail.getKey())) {
							find = true;
							break;
						}
					}
					
					//未在计划中就需要加进去
					if(!find) {
						BorrowPlanVO planVO = new BorrowPlanVO();
						BeanUtils.copyProperties(detail.getValue().get(0), planVO);
						planVO.setPlanQuatity(BigDecimal.ZERO);
						planVO.setActualQuatity(new BigDecimal(detail.getValue().size()));
						noPlan.add(planVO);
					}
				}
				
				if(!noPlan.isEmpty()) {
					result.addAll(noPlan);
				}
			}
		}
	}
	
	/**
	 * 
	 * @description 检查领用主表id
	 * @param userId
	 * @param masterId
	 * @return
	 * @auther 韩兵
	 * @Date 2020年7月7日
	 * @return Long
	 */
	private String checkBorrowMasterId(String userId,String masterId) {
		ToolBorrowMaster master = null;
		if(StringUtils.isBlank(masterId)) {
			log.info("------------------------------生成领用任务主表-------------------------------------------------");
			//获取ocr结果
			CacheOcrModel cache = (CacheOcrModel)CacheOperatorInfo.getMapValue(
					CacheKeyName.CACHE_BORROW_OCR_SCAN.getValue(), null);
			//选择的任务
			String taskId = (String)CacheOperatorInfo.getMapValue(
					CacheKeyName.CACHE_BORROW_TASK_ID.getValue(), null);
			//手写任务
			BorrowToolTaskDTO toolTask = (BorrowToolTaskDTO)CacheOperatorInfo.getMapValue(
					CacheKeyName.CACHE_BORROW_REASON.getValue(), null);
			Date startTime = null;
			Date stopTime = null;
			try {
				startTime = null==cache?null==toolTask?
						null:StringUtils.isBlank(toolTask.getStartTime())?null:DateUtils.getInstance().getDateByStr(toolTask.getStartTime(), DateUtils.getInstance().SDF):
							StringUtils.isBlank(cache.getStartTime())?null:DateUtils.getInstance().getDateByStr(cache.getStartTime(), DateUtils.getInstance().SDF);
				stopTime = null==cache?null==toolTask?
						null:StringUtils.isBlank(toolTask.getEndTime())?null:DateUtils.getInstance().getDateByStr(toolTask.getEndTime(), DateUtils.getInstance().SDF):
							StringUtils.isBlank(cache.getEndTime())?null:DateUtils.getInstance().getDateByStr(cache.getEndTime(), DateUtils.getInstance().SDF);
			}catch(Exception e) {
				log.error("时间格式化异常",e);
			}
			String taskCode = null==cache?null==toolTask?"":toolTask.getTaskCode():cache.getOcrCode();
			String taskName = null==cache?null==toolTask?"":toolTask.getTaskName():cache.getOcrName();
			String ocrImg = null==cache?null:cache.getOcrImg();
			if(!StringUtils.isBlank(taskId)) {
				ToolUseTask task = toolUseTaskMapper.selectById(taskId);
				startTime = task.getStartTime();
				stopTime = task.getEndTime();
				taskName = task.getName();
			}
			
			master = new ToolBorrowMaster();
			master.setCreateUser(WebUtils.username());
			master.setCreateTime(new Date());
			master.setUserId(userId);
			master.setStatus(0);
			master.setPlanId(taskId);
			master.setTaskCode(taskCode);
			master.setTaskName(taskName);
			master.setTaskImg(ocrImg);
			master.setStartTime(startTime);
			master.setStopTime(stopTime);
			toolBorrowMasterMapper.insert(master);
			masterId = master.getId();
			CacheOperatorInfo.setMapValue(CacheKeyName.BUSINESS_MASTER_ID.getValue(), masterId);
			CacheOperatorInfo.setMapValue(CacheKeyName.BUSINESS_OPERATE_TYPE.getValue(), OperateType.USE_OUT_WAREHOUSE.getValue());
		}
		return masterId;
	}
	
	/**
	 * 
	 * @description 检查归还主表
	 * @param userId
	 * @param masterId
	 * @return
	 * @auther 韩兵
	 * @Date 2020年7月8日
	 * @return Long
	 */
	private String checkReturnMasterId(String userId,String masterId) {
		ToolReturnMaster master = null;
		if(StringUtils.isBlank(masterId)) {
			master = new ToolReturnMaster();
			master.setCreateTime(new Date());
			master.setUserId(userId);
			master.setStatus(0);
			toolReturnMasterMapper.insert(master);
			masterId = master.getId();
			CacheOperatorInfo.setMapValue(CacheKeyName.BUSINESS_MASTER_ID.getValue(), masterId);
			CacheOperatorInfo.setMapValue(CacheKeyName.BUSINESS_OPERATE_TYPE.getValue(), OperateType.USE_IN_WAREHOUSE.getValue());
		}
		return masterId;
	}



	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	@Transactional
	public ApiResult confirmBorrow(Boolean confirm, String taskName, String startTime, String endTime) {
		//synchronized (lock) {
			//处理业务
			String masterId = (String)CacheOperatorInfo.getMapValue(CacheKeyName.BUSINESS_MASTER_ID.getValue(),null);
			
			Long expiredCount = toolBorrowMapper.selectExpiredCountByPlanId(masterId);
			
			if(expiredCount > 0 && confirm) {
				return ApiResult.fail("-3","有"+expiredCount+"个工器具过期,是否确认继续领取?");
			}
			
			ApiResult confirmDoor = commonBiz.confirmDeviceDoor();
			if(!confirmDoor.isSuccess()) {
				return ApiResult.fail("-2","请关闭工器具柜门");
			}
			
			ToolBorrowMaster master = toolBorrowMasterMapper.selectById(masterId);
			if(null != master) {
				master.setStatus(1);
				master.setTaskName(taskName);
				if(!StringUtils.isBlank(startTime)) {
					master.setStartTime(DateUtils.getInstance().getDateByStr(startTime, DateUtils.getInstance().SDF));
				}
				if(!StringUtils.isBlank(endTime)) {
					master.setStopTime(DateUtils.getInstance().getDateByStr(endTime, DateUtils.getInstance().SDF));
				}
				toolBorrowMasterMapper.updateById(master);
				
				List<ToolBorrowDetail> details = toolBorrowDetailMapper.selectList(new Condition<ToolBorrowDetail>().eq("master_id", masterId));
				
				List<ToolBorrowPlanDetail> planDetails = this.getBorrowPlan("");
				
				if(null != details && !details.isEmpty()) {
					
					if(details.size() < planDetails.size()) {
						log.info("未领取完成！");
					}
					details.stream().forEach(detail->{
						ToolBorrowReturnRecord record = new ToolBorrowReturnRecord();
						record.setCreateTime(new Date());
						record.setDeviceId(detail.getDeviceId());
						record.setOperatorUserId(master.getUserId());
						record.setToolId(detail.getToolId());
						record.setType(ToolBorrowReturnRecord.TYPE_BORROW);
						record.setBusinessId(master.getId());
						toolBorrowReturnRecordMapper.insert(record);
					});
					
					//更新工器具状态
					List<String> toolIds = details.stream().map(ToolBorrowDetail::getToolId).collect(Collectors.toList());
					toolMapper.updateToolStatus(toolIds, 0, 1);
					//发送信息到主站
//					String jobPlanId = (String)CacheOperatorInfo.getMapValue(
//							CacheKeyName.CACHE_BORROW_TASK_ID.getValue(), null);
//					String jobName = "";
//					String jobContent = "";
//					User user = userMapper.selectById(master.getUserId());
//					String useUser = user.getName();
//					if(StringUtils.isBlank(jobPlanId)) {
//						jobName = taskName;
//						jobContent = taskName;
//					}
					//commonSendInfo.sendToolUseOut(toolIds, jobPlanId,master.getUserId(), useUser, jobName, 
					//		jobContent, startTime, endTime,masterId);
					
					//发送更新的工器具状态
					//commonSendInfo.sendToolInfoByIds(toolIds);
				}
			}
			//发送关闭柜子的命令
			commonBiz.lockDevice();
			//设置熄灭灯的柜子
			List<String> allDeviceCode = deviceService.getAllDeviceCode(null);
			commonBiz.sendLightCommand(allDeviceCode, 0);
			CacheOperatorInfo.setMapValue(CacheKeyName.BUSINESS_MASTER_ID.getValue(), null);
			CacheOperatorInfo.setMapValue(CacheKeyName.VALIDATED_USER_ID.getValue(), null);
			return ApiResult.success();
		//}
	}

	@Override
	public List<BorrowPlanVO> selectReturnStatisticsByUserId() {
		String userId = commonBiz.checkValidatedUserId();
		return toolBorrowMapper.selectHasNoReturnToolByUserId(userId);
	}

	@Override
	public PageResult<ReturnDetailVO> selectReturnDetailByMasterId(PageRequest dto) {
		String userId = commonBiz.checkValidatedUserId();
		String masterId = (String)CacheOperatorInfo.getMapValue(CacheKeyName.BUSINESS_MASTER_ID.getValue(), null);
		if(StringUtils.isBlank(masterId)) {
			masterId = this.checkReturnMasterId(userId, masterId);
		}
		PageHelper.startPage(dto);
	    List<ReturnDetailVO> result = toolBorrowMapper.selectReturnDetailByMasterId(masterId,userId);
	    
	    if(null != result && !result.isEmpty()) {
	    	List<String> typeIds = result.stream().map(ReturnDetailVO::getModelId).collect(Collectors.toList());
	    	List<DeviceSurplusTool> surpluses = commonMapper.selectDeviceSurplusTools(typeIds);
	    	result.stream().forEach(vo->{
	    		for(DeviceSurplusTool surplus : surpluses) {
	    			if(vo.getModelId().equals(surplus.getTypeId())) {
	    				vo.setBoxNum(surplus.getDeviceCode());
	    				break;
	    			}
	    		}
	    	});
	    }
	    
	    return PageUtils.toPageResult(result);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	@Transactional
	public ApiResult confirmRetrun() {
		//synchronized (lock) {
			//检查柜门情况
			ApiResult confirmDoor = commonBiz.confirmDeviceDoor();
			if(!confirmDoor.isSuccess()) {
				return confirmDoor;
			}
			
			//处理业务
			String masterId = (String)CacheOperatorInfo.getMapValue(CacheKeyName.BUSINESS_MASTER_ID.getValue(),null);
			ToolReturnMaster master = toolReturnMasterMapper.selectById(masterId);
			if(null != master) {
				master.setStatus(1);
				toolReturnMasterMapper.updateById(master);
				List<ToolReturnDetail> details = toolReturnDetailMapper.selectList(new Condition<ToolReturnDetail>().eq("master_id", masterId));
				if(null != details && !details.isEmpty()) {
					//查询借的记录，并且将借的记录更新为已归还
					List<String> returnToolIds = details.stream().map(ToolReturnDetail::getToolId).collect(Collectors.toList());
					List<ToolBorrowDetail> borrowDetails = toolBorrowMapper.selectWaitUpdateBorrowDetails(returnToolIds);
					if(null != borrowDetails && !borrowDetails.isEmpty()) {
						for(ToolBorrowDetail borrowDetail : borrowDetails) {
							for(ToolReturnDetail returnDetail : details) {
								if(borrowDetail.getToolId().equals(returnDetail.getToolId())) {
									borrowDetail.setHasReturn(1);
									borrowDetail.setLastUpdateTime(new Date());
									borrowDetail.setReturnDeviceId(returnDetail.getDeviceId());
									borrowDetail.setReturnTime(new Date());
									borrowDetail.setReturnUserId(master.getUserId());
									toolBorrowDetailMapper.updateById(borrowDetail);
								}
							}
						}
					}
					List<BorrowReturnRecordSchema> masterList = new ArrayList<BorrowReturnRecordSchema>();
					details.stream().forEach(detail->{
						ToolBorrowReturnRecord record = new ToolBorrowReturnRecord();
						record.setCreateTime(new Date());
						record.setDeviceId(detail.getDeviceId());
						record.setOperatorUserId(master.getUserId());
						record.setToolId(detail.getToolId());
						record.setType(ToolBorrowReturnRecord.TYPE_RETURN);
						record.setBusinessId(master.getId());
						toolBorrowReturnRecordMapper.insert(record);
						try {
							BorrowReturnRecordSchema masterSchema = new BorrowReturnRecordSchema();
							ToolModel tool = toolMapper.selectById(detail.getToolId());
							DeviceModel device = deviceMapper.selectById(detail.getDeviceId());
							masterSchema.setDeviceCode(device.getCode());
							masterSchema.setEpc(tool.getCode());
							masterSchema.setOperateDate(DateUtils.getInstance().getDateStr(record.getCreateTime(), DateUtils.getInstance().SDF_HH));
							masterSchema.setOperateType(ToolBorrowReturnRecord.TYPE_RETURN);
							masterSchema.setOperateUserId(master.getUserId());
							masterList.add(masterSchema);
						}catch(Exception e) {
							log.error("发送领使用记录到主站异常：{}",e);
						}
					});
					
					//将借据更新为已归还
					List<String> toolIds = details.stream().map(ToolReturnDetail::getToolId).collect(Collectors.toList());
					toolBorrowMapper.updateBorrowToReturn(toolIds);
					//更新工器具状态
					toolMapper.updateToolStatus(toolIds, 2, null);
					
					//发送信息到主站
					//String userId = commonBiz.checkValidatedUserId();
					//User u = userMapper.selectById(userId);
					//String useUser = u==null?"":u.getName();
					//commonSendInfo.sendToolUseBack(toolIds,userId, useUser,masterId);
					
					//发送更新的工器具状态
					//commonSendInfo.sendToolInfoByIds(toolIds);
					
					//更新异常清单的入库时间
					commonMapper.updateToolExceptionInWarehouseTime(toolIds);
				}
			}
			//发送关闭柜子的命令
			commonBiz.lockDevice();
			CacheOperatorInfo.setMapValue(CacheKeyName.BUSINESS_MASTER_ID.getValue(), null);
			CacheOperatorInfo.setMapValue(CacheKeyName.VALIDATED_USER_ID.getValue(), null);
			return ApiResult.success();
		//}
	}

	@Override
	public PageResult<ToolBorrowReturnRecordVO> selectToolBorrowReturnRecord(ToolBorrowReturnRecordDTO dto) {
		if(!StringUtils.isBlank(dto.getQueryStartTime())) {
			dto.setQueryStartTime(dto.getQueryStartTime() + " 00:00:00:000");
		}
		if(!StringUtils.isBlank(dto.getQueryEndTime())) {
			dto.setQueryEndTime(dto.getQueryEndTime() + " 23:59:59:999");
		}
		PageHelper.startPage(dto);
	    List<ToolBorrowReturnRecordVO> result = toolBorrowMapper.selectToolBorrowReturnRecord(dto);
	    if(null != result && result.size() > 0) {
	    	result.stream().forEach(vo->{
	    		if(!StringUtils.isBlank(vo.getTaskImg())) {
	    			vo.setTaskImg(imgUtil.formatImgPath(FormatImgPre.PRE_ORC.getValue()+vo.getTaskImg()));
	    		}
	    	});
	    }
	    return PageUtils.toPageResult(result);
	}

	@Override
	public void productBorrowRecord(DeviceWarehouseDTO deviceWarehouse) {
		if(null != deviceWarehouse && null != deviceWarehouse.getToolCodes() && 
				!deviceWarehouse.getToolCodes().isEmpty()) {
			List<String> existCodes = null;
			DeviceLastWarehouseParamDTO param = new DeviceLastWarehouseParamDTO();
			param.setOffSet(0);
			param.setDeviceCode(deviceWarehouse.getDeviceCode());
			param.setLimit(1);
			List<ToolWarehouseDetail> lastWarehouseRecord = toolMapper.selectLastWarehouseRecordByDeviceCode(param);
			if(null != lastWarehouseRecord && !lastWarehouseRecord.isEmpty()) {
				existCodes = lastWarehouseRecord.stream().map(r->r.getToolCode()).collect(Collectors.toList());
				existCodes.removeAll(deviceWarehouse.getToolCodes());
			}
			
			if(null!= deviceWarehouse.getToolCodes() && !deviceWarehouse.getToolCodes().isEmpty()) {
				String userId = commonBiz.checkValidatedUserId();
				String masterId = null;
				if(!StringUtils.isBlank(userId)) {
					@SuppressWarnings("unchecked")
					DeviceModel device = deviceMapper.selectOne(new Condition<DeviceModel>().eq("code", deviceWarehouse.getDeviceCode()));
					masterId = (String)CacheOperatorInfo.getMapValue(CacheKeyName.BUSINESS_MASTER_ID.getValue(), null);
					if(StringUtils.isBlank(masterId)) {
						masterId = this.checkBorrowMasterId(userId, null);
					}
					for(String toolCode : existCodes) {
						@SuppressWarnings("unchecked")
						ToolModel tool = toolMapper.selectOne(new Condition<ToolModel>().eq("code", toolCode));
						ToolBorrowDetail detail = new ToolBorrowDetail();
						detail.setMasterId(masterId);
						detail.setCreateTime(new Date());
						detail.setCreateUser(WebUtils.username());
						detail.setDeviceId(device.getId());
						detail.setExpiredTime(tool.getExpiredDate());
						detail.setHasReturn(0);
						detail.setToolId(tool.getId());
						toolBorrowDetailMapper.insert(detail);
					}
				}
			}
		}
	}

	@Override
	public void productReturnRecord(DeviceWarehouseDTO deviceWarehouse) {
		if(null != deviceWarehouse && null != deviceWarehouse.getToolCodes() && 
				!deviceWarehouse.getToolCodes().isEmpty()) {
			DeviceLastWarehouseParamDTO param = new DeviceLastWarehouseParamDTO();
			param.setOffSet(0);
			param.setDeviceCode(deviceWarehouse.getDeviceCode());
			param.setLimit(1);
			List<ToolWarehouseDetail> lastWarehouseRecord = toolMapper.selectLastWarehouseRecordByDeviceCode(param);
			if(null != lastWarehouseRecord && !lastWarehouseRecord.isEmpty()) {
				List<String> existCodes = lastWarehouseRecord.stream().map(r->r.getToolCode()).collect(Collectors.toList());
				deviceWarehouse.getToolCodes().removeAll(existCodes);
			}
			
			if(null!= deviceWarehouse.getToolCodes() && !deviceWarehouse.getToolCodes().isEmpty()) {
				String userId = commonBiz.checkValidatedUserId();
				String masterId = null;
				if(!StringUtils.isBlank(userId)) {
					@SuppressWarnings("unchecked")
					DeviceModel device = deviceMapper.selectOne(new Condition<DeviceModel>().eq("code", deviceWarehouse.getDeviceCode()));
					masterId = (String)CacheOperatorInfo.getMapValue(CacheKeyName.BUSINESS_MASTER_ID.getValue(), null);
					if(StringUtils.isBlank(masterId)) {
						masterId = this.checkReturnMasterId(userId, null);
					}
					for(String toolCode : deviceWarehouse.getToolCodes()) {
						@SuppressWarnings("unchecked")
						ToolModel tool = toolMapper.selectOne(new Condition<ToolModel>().eq("code", toolCode));
						ToolReturnDetail detail = new ToolReturnDetail();
						detail.setMasterId(masterId);
						detail.setCreateTime(new Date());
						detail.setCreateUser(WebUtils.username());
						detail.setDeviceId(device.getId());
						detail.setToolId(tool.getId());
						toolReturnDetailMapper.insert(detail);
					}
				}
			}
		}
	}

	@SuppressWarnings("rawtypes")
	@Override
	@Transactional
	public ApiResult toolExceptionRecord(String toolId) {
		@SuppressWarnings("unchecked")
		ToolException exception = toolExceptionMapper.selectOne(new Condition<ToolException>().eq("tool_id", toolId).eq("status", 0));
		if(exception == null) {
			//新增
			exception = new ToolException();
			exception.setStatus(0);
		}else {
			//取消
			exception.setStatus(-1);
		}
		//判断当前的操作是什么，确定出库入库时间
		Integer operateType = (Integer)CacheOperatorInfo.getMapValue(
				CacheKeyName.BUSINESS_OPERATE_TYPE.getValue(),0);
		if(0 != operateType) {
			if(OperateType.USE_IN_WAREHOUSE.getValue() == operateType) {
				ToolBorrowDetail toolBorrowDetail = this.getOutAndInDate(toolId);
				if(null != toolBorrowDetail) {
					exception.setOutWarehouseTime(toolBorrowDetail.getCreateTime());
					if(toolBorrowDetail.getHasReturn()==1) {
						exception.setIntWarehouseTime(toolBorrowDetail.getReturnTime());
					}
				}
			}
			
			if(OperateType.INSPECT_IN_WAREHOUSE.getValue() == operateType) {
				@SuppressWarnings("unchecked")
				List<ToolInspectDetail> toolInspectDetails = inspectDetailMapper.selectList(
						new Condition<ToolInspectDetail>().eq("tool_id", toolId).order("out_warehouse_time", "desc"));
				if(null != toolInspectDetails && !toolInspectDetails.isEmpty()) {
					exception.setOutWarehouseTime(toolInspectDetails.get(0).getOutWarehouseTime());
					exception.setIntWarehouseTime(toolInspectDetails.get(0).getInWarehouseTime());
				}
			}
		}
		exception.setToolId(toolId);
		exception.setOperatorUserId(commonBiz.checkValidatedUserId());
		toolExceptionMapper.saveOrUpdate(exception);
		return ApiResult.success();
	}
	
	@Override
	public Integer getBorrowQuantity(String id) {
		Integer quantity = toolBorrowMapper.getBorrowQuantity(id);
		return quantity;
	}

	@Override
	public List<Map<String, String>> getBorrowQuantityEachType(String id) {
		List<Map<String, String>> list = toolBorrowMapper.getBorrowQuantityEachType(id);
		return list;
	}

	@Override
	public List<Map<String, String>> getBorrowRfidAndModel(String id) {
		List<Map<String, String>> list = toolBorrowMapper.getBorrowRfidAndModel(id);
		return list;
	}

	@Override
	public Integer getScanQuantity(List<String> rfids) {
		Integer quantity = toolBorrowMapper.getScanQuantity(rfids);
		return quantity;
	}
	
	@Override
	public List<Map<String, String>> getScanQuantityEachType(List<String> rfids) {
		List<Map<String, String>> list = toolBorrowMapper.getScanQuantityEachType(rfids);
		return list;
	}

	@Override
	public List<Map<String, String>> getScanRfidAndModel(List<String> rfids) {
		List<Map<String, String>> list = toolBorrowMapper.getScanRfidAndModel(rfids);
		return list;
	}

	@Override
	public DevicePdVO getDevicePdInfo(List<String> rfids, String id) {
		DevicePdVO result = new DevicePdVO();
		List<Map<String, String>> defectQuantityEachType = new ArrayList<Map<String, String>>();
		List<Map<String, String>> defectRfidAndModel = new ArrayList<Map<String, String>>();
		List<Map<String, String>> scanRfidAndModel = new ArrayList<Map<String, String>>();
		List<Map<String, String>> borrowRfidAndModel = new ArrayList<Map<String, String>>();
		Integer borrowQuantity = toolBorrowMapper.getBorrowQuantity(id); //查询领用数量
		Integer scanQuantity = toolBorrowMapper.getScanQuantity(rfids); //查询扫描数量
		Integer defectQuantity = borrowQuantity - scanQuantity; //缺失数量
		if(defectQuantity < 0)
			defectQuantity = 0;
		scanRfidAndModel = toolBorrowMapper.getScanRfidAndModel(rfids); //查询扫描rfid和型号
		borrowRfidAndModel = toolBorrowMapper.getBorrowRfidAndModel(EtmWebUtil.userId()); //查询领用rfid和型号
		List<String> scanRfidList = new ArrayList<String>();
		List<String> borrowRfidList = new ArrayList<String>();
		for(Map<String, String> map : scanRfidAndModel) { //把rfid拎出来以计算差集
			scanRfidList.add(map.get("rfid"));
		}
		for(Map<String, String> map : borrowRfidAndModel) {
			borrowRfidList.add(map.get("rfid"));
		}
		List<String> defectRfidList = new ArrayList<String>(borrowRfidList);
		defectRfidList.removeAll(scanRfidList); //缺失的rfid
		defectQuantityEachType = toolBorrowMapper.getDefectQuantityEachType(defectRfidList, EtmWebUtil.userId()); //缺失的各类型数量
		defectRfidAndModel = toolBorrowMapper.getDefectRfidAndModel(defectRfidList, EtmWebUtil.userId()); //缺失的rfid和型号
		result.setDefectQuantity(defectQuantity);
		result.setDefectQuantityEachType(defectQuantityEachType);
		result.setDefectRfidAndModel(defectRfidAndModel);
		result.setScanQuantity(scanQuantity);
		result.setScanRfidAndModel(scanRfidAndModel);
		return result;
	}

	@Override
	public ToolQueryVO getToolDetail(String rfid) {
		ToolQueryVO toolQueryVO = toolBorrowMapper.getToolDetail(rfid);
		toolQueryVO.setImg(imgUtil.formatImgPath(FormatImgPre.PRE_TOOL.getValue()+toolQueryVO.getImg()));
		return toolQueryVO;
	}

	@Override
	public ToolBorrowDetail getOutAndInDate(String id) {
		ToolBorrowDetail toolBorrowDetail = toolBorrowMapper.getOutAndInDate(id);
		return toolBorrowDetail;
	}

	@Override
	public void updateBorrowDetailStatus(String id) {
		toolBorrowMapper.updateBorrowDetailStatus(id);
	}
	
	@Override
	public List<Map<String, String>> getToolTypeList() {
		List<Map<String, String>> list = toolBorrowMapper.getToolTypeList();
		return list;
	}
	
	@Override
	public List<ToolBorrowPlanDetail> getBorrowPlan(String planName) {
		List<ToolBorrowPlanDetail> planDetails = toolBorrowMapper.
				queryBorrowPlanDetailByPlanName(planName);
		return planDetails;
	}

	@Override
	public ApiResult<?> planBookImg(String img) {
		ApiResult<?> result = commonBiz.acquireBorrowPlanMasterId(img);
		return result;
	}

}
